﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using Common;
using Domain.Common;
using Domain.Map;
using MapComponentSprite.Global;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace MapComponentSprite
{
    public class MapBackgroundLayerSprite : UserControlledSprite
    {
        private static MapBackgroundLayerSprite _mapBackgroundLayerSprite;//单例模式对象
        private static object obj=new object();//单例模式对象锁
        /// <summary>
        /// 地图单位行和列总数
        /// </summary>
        public static int MapUnitCount = 30;
        public static string Name = "yueluo_1.0";
        public static float MapScrollSpeed = 0.8f;//地图移动速率
        public static float ScrollSpeedScale = 1f;//地图移动速率调节参数

       
        /// <summary>
        /// 是否需要跳转地图
        /// </summary>
        public static bool NeedJump { get; set; }
        private static MapUnitSprite[,] mapUnitSprites;
        public static List<MapUnitSprite> DisplayMapUnitSprites = new List<MapUnitSprite>();//要呈现视图中的地图单元集合
        public static Dictionary<int, Texture2D> MapUnitSpritesCache = new Dictionary<int, Texture2D>();//地图单元缓存，实现高效读取
        private static float _oldScrollWheelValue = 0;

        private MapBackgroundLayerSprite()
        {
            NeedJump = true;
            this.Showing = true;
            InitMapUnitSpritesArray();
            GameScreen.ResetScreenEdge(MapUnit.Width, MapUnit.Height, Game.GraphicsDevice.Viewport);
        }

        public static MapBackgroundLayerSprite GetInstance()
        {
            lock (obj)
            {
                if (_mapBackgroundLayerSprite != null)
                    return _mapBackgroundLayerSprite;
                else
                {
                    _mapBackgroundLayerSprite = new MapBackgroundLayerSprite();
                    return _mapBackgroundLayerSprite;
                }
            }
            
        }
        /// <summary>
        /// 初始化地图单元对象数组
        /// </summary>
        private static void InitMapUnitSpritesArray()
        {
            if (mapUnitSprites == null)
            {
                mapUnitSprites = new MapUnitSprite[MapUnitCount, MapUnitCount];
                for (int i = 0; i < MapUnitCount; i++)
                {
                    for (int j = 0; j < MapUnitCount; j++)
                    {
                        var unit = new MapUnitSprite();
                        unit.Position = new Point(j, i); //按【列,行】记录位置
                        unit.NumberName = (i + j * MapUnitCount).ToString();
                        mapUnitSprites[i, j] = unit;
                    }
                }
            }
        }

        public override void Draw(GameTime gameTime)
        {
            if (!Showing)
                return;
            DisplayMapUnitSpritesLoad();
            foreach (MapUnitSprite map in DisplayMapUnitSprites)
            {
                map.Draw(gameTime );
            }
        }

        public override void Update(GameTime gameTime)
        {
            if (!Showing)
                return;
            if (NeedJump)
            {
                MapJumpToDestination(new Point(215, 130));
                NeedJump = false;
            }
            UpdateMoveMap(gameTime);
            UpdateScrollWheelMapSize();
            DrawPosition.Width = GameScreen.ViewportSize.X;
            DrawPosition.Height = GameScreen.ViewportSize.Y;
            ClickLeftEventListener(false);
            ClickRightEventListener(false);
        }
        /// <summary>
        /// 将在要显示在窗口中的地图集合
        /// </summary>
        public void DisplayMapUnitSpritesLoad()
        {
            DisplayMapUnitSprites.Clear();
            for (int i = GameScreen.TopLeftPosition.X; i <= GameScreen.BottomRightPosition.X + MapUnit.Magnify; i += MapUnit.Magnify)
            {
                for (int j = GameScreen.TopLeftPosition.Y; j <= GameScreen.BottomRightPosition.Y + MapUnit.Magnify; j += MapUnit.Magnify)
                {
                    if ((((i >= 0) && (i < Map.MapDimensions.X)) && (j >= 0)) && (j < Map.MapDimensions.Y))
                    {
                        DisplayMapUnitSprites.Add(mapUnitSprites[i / MapUnit.Magnify, j / MapUnit.Magnify]);
                    }
                }
            }
            //设置显示地图单元所在窗口位置（X,Y）
            foreach (MapUnitSprite map in DisplayMapUnitSprites)
            {
                map.Destination.X = GameScreen.LeftEdge + (map.Position.Y * MapUnit.Width * MapUnit.Magnify);//计算X坐标起始绘制点
                map.Destination.Y = GameScreen.TopEdge + (map.Position.X * MapUnit.Height * MapUnit.Magnify);//计算Y坐标起始绘制点
                //设定绘图的宽高
                map.Destination.Width = MapUnit.Width * MapUnit.Magnify;
                map.Destination.Height = MapUnit.Height * MapUnit.Magnify;
            }

        }
        /// <summary>
        /// 处理键盘方向键移动地图位置
        /// </summary>
        /// <param name="gameTime"></param>
        private void UpdateMoveMap(GameTime gameTime)
        {
            #region 判断键盘或鼠标移动地图方向
            MapMoveType mapMoveType = MapMoveType.Stop;
            KeyboardState keystate = Keyboard.GetState();
            MouseState mousestate = Mouse.GetState();
            if (keystate.IsKeyDown(Keys.Left) || keystate.IsKeyDown(Keys.A) || (mousestate.X == 0&&Graphics.IsFullScreen))
            {
                if (keystate.IsKeyDown(Keys.Up) || keystate.IsKeyDown(Keys.W))
                    mapMoveType = MapMoveType.TopLeft;
                else if (keystate.IsKeyDown(Keys.Down) || keystate.IsKeyDown(Keys.S))
                    mapMoveType = MapMoveType.BottomLeft;
                else
                    mapMoveType = MapMoveType.Left;
            }

            if (keystate.IsKeyDown(Keys.Right) || keystate.IsKeyDown(Keys.D) || (mousestate.X == GameScreen.ViewportSize.X&&Graphics.IsFullScreen))
            {
                if (keystate.IsKeyDown(Keys.Up) || keystate.IsKeyDown(Keys.W))
                    mapMoveType = MapMoveType.TopRight;
                else if (keystate.IsKeyDown(Keys.Down) || keystate.IsKeyDown(Keys.S))
                    mapMoveType = MapMoveType.BottomRight;
                else
                    mapMoveType = MapMoveType.Right;
            }
            if (keystate.IsKeyDown(Keys.Up) || keystate.IsKeyDown(Keys.W) || (mousestate.Y == 0 && Graphics.IsFullScreen))
                mapMoveType = MapMoveType.Top;
            if (keystate.IsKeyDown(Keys.Down) || keystate.IsKeyDown(Keys.S) || (mousestate.Y == GameScreen.ViewportSize.Y && Graphics.IsFullScreen))
                mapMoveType = MapMoveType.Bottom;
            #endregion
            if (mapMoveType != MapMoveType.Stop)
            {

                int num = (int)((gameTime.ElapsedGameTime.Milliseconds * MapScrollSpeed) * ScrollSpeedScale);
                switch (mapMoveType)
                {
                    case MapMoveType.Left:
                        if (GameScreen.ViewportSize.X < Map.Width)  //窗口像素宽度<地图总像素宽度
                        {
                            GameScreen.LeftEdge += num;
                            if (GameScreen.LeftEdge > 0)  //LeftEdge一般为负值，大于0，说明视窗已经到了地图最左边了，不能继续左移
                            {
                                GameScreen.LeftEdge = 0;
                            }
                        }
                        break;

                    case MapMoveType.Right:
                        if (GameScreen.ViewportSize.X < Map.Width)
                        {
                            GameScreen.LeftEdge -= num;
                            if (GameScreen.LeftEdge < (GameScreen.ViewportSize.X - Map.Width)) //LeftEdge视窗左边缘最大，右边缘已经到达地图最右边
                            {
                                GameScreen.LeftEdge = GameScreen.ViewportSize.X - Map.Width;
                            }
                        }
                        break;

                    case MapMoveType.Top:
                        if (GameScreen.ViewportSize.Y < Map.Height)
                        {
                            GameScreen.TopEdge += num;
                            if (GameScreen.TopEdge > 0) //TopEdge一般为负值，大于0，说明视窗已经到了地图最上边了，不能继续上移
                            {
                                GameScreen.TopEdge = 0;
                            }
                        }
                        break;

                    case MapMoveType.Bottom:
                        if (GameScreen.ViewportSize.Y < Map.Height)
                        {
                            GameScreen.TopEdge -= num;
                            if (GameScreen.TopEdge < (GameScreen.ViewportSize.Y - Map.Height))
                            {
                                GameScreen.TopEdge = GameScreen.ViewportSize.Y - Map.Height;
                            }
                        }
                        break;

                    case MapMoveType.TopLeft:
                        if (GameScreen.ViewportSize.X < Map.Width)
                        {
                            GameScreen.LeftEdge += num;
                            if (GameScreen.LeftEdge > 0)
                            {
                                GameScreen.LeftEdge = 0;
                            }
                        }
                        if (GameScreen.ViewportSize.Y < Map.Height)
                        {
                            GameScreen.TopEdge += num;
                            if (GameScreen.TopEdge > 0)
                            {
                                GameScreen.TopEdge = 0;
                            }
                        }
                        break;

                    case MapMoveType.TopRight:
                        if (GameScreen.ViewportSize.X < Map.Width)
                        {
                            GameScreen.LeftEdge -= num;
                            if (GameScreen.LeftEdge < (GameScreen.ViewportSize.X - Map.Width))
                            {
                                GameScreen.LeftEdge = GameScreen.ViewportSize.X - Map.Width;
                            }
                        }
                        if (GameScreen.ViewportSize.Y < Map.Height)
                        {
                            GameScreen.TopEdge += num;
                            if (GameScreen.TopEdge > 0)
                            {
                                GameScreen.TopEdge = 0;
                            }
                        }
                        break;

                    case MapMoveType.BottomLeft:
                        if (GameScreen.ViewportSize.X < Map.Width)
                        {
                            GameScreen.LeftEdge += num;
                            if (GameScreen.LeftEdge > 0)
                            {
                                GameScreen.LeftEdge = 0;
                            }
                        }
                        if (GameScreen.ViewportSize.Y < Map.Height)
                        {
                            GameScreen.TopEdge -= num;
                            if (GameScreen.TopEdge < (GameScreen.ViewportSize.Y - Map.Height))
                            {
                                GameScreen.TopEdge = GameScreen.ViewportSize.Y - Map.Height;
                            }
                        }
                        break;

                    case MapMoveType.BottomRight:
                        if (GameScreen.ViewportSize.X < Map.Width)
                        {
                            GameScreen.LeftEdge -= num;
                            if (GameScreen.LeftEdge < (GameScreen.ViewportSize.X - Map.Width))
                            {
                                GameScreen.LeftEdge = GameScreen.ViewportSize.X - Map.Width;
                            }
                        }
                        if (GameScreen.ViewportSize.Y < Map.Height)
                        {
                            GameScreen.TopEdge -= num;
                            if (GameScreen.TopEdge < (GameScreen.ViewportSize.Y - Map.Height))
                            {
                                GameScreen.TopEdge = GameScreen.ViewportSize.Y - Map.Height;
                            }
                        }
                        break;
                }
                GameScreen.ResetScreenEdge(MapUnit.Width, MapUnit.Height, Game.GraphicsDevice.Viewport);
                return;
            }

            return;
        }
        /// <summary>
        /// 鼠标滚轮时间更新地图大小
        /// </summary>
        private void UpdateScrollWheelMapSize()
        {
            MouseState mousestate = Mouse.GetState();
            //滚轮时
            if (mousestate.ScrollWheelValue != _oldScrollWheelValue)
            {
                float num = mousestate.ScrollWheelValue - _oldScrollWheelValue;
                _oldScrollWheelValue = mousestate.ScrollWheelValue;
                if (num > 0f)//滚轮向前，放大地图
                {
                    num = 0.1f;//固定滚动增量
                    if (MapUnit.Width >= MapUnit.WidthMax || MapUnit.Height >= MapUnit.HeightMax)//地图单位放大的最大值，超过无效
                    {
                        return;
                    }
                }
                if (num < 0f)//滚轮向后，缩小地图
                {
                    num = -0.1f;
                    if (MapUnit.Width <= MapUnit.WidthMin || MapUnit.Height <= MapUnit.HeightMin)//地图单位缩小的最小值，超过无效
                    {
                        return;
                    }
                }
                //计算当期缩放后地图尺寸
                int currentWidth = (int)((1f + num) * MapUnit.Width);
                int currentHeight = (int)((1f + num) * MapUnit.Height);
                if (currentWidth > MapUnit.WidthMax)
                {
                    currentWidth = MapUnit.WidthMax;
                }
                else if (currentWidth < MapUnit.WidthMin)
                {
                    currentWidth = MapUnit.WidthMin;
                }
                if (currentHeight > MapUnit.HeightMax)
                {
                    currentHeight = MapUnit.HeightMax;
                }
                else if (currentHeight < MapUnit.HeightMin)
                {
                    currentHeight = MapUnit.HeightMin;
                }
                int oldWidth = MapUnit.Width;
                MapUnit.Width = currentWidth;//记录滚轮调整后的地图单位的宽度
                MapUnit.Height = currentHeight;//记录滚轮调整后的地图单位的高度
                //计算视窗在地图中的新坐标位置，以及更新地图单位默认宽高
                num = (((float)currentWidth) / ((float)oldWidth)) - 1f;
                int num4 = GameScreen.LeftEdge + ((int)(num * (GameScreen.LeftEdge - mousestate.X)));
                int num5 = GameScreen.TopEdge + ((int)(num * (GameScreen.TopEdge - mousestate.Y)));
                if (((((GameScreen.ViewportSize.X - num4) <= Map.Width) && (num4 <= 0)) && ((GameScreen.ViewportSize.Y - num5) <= Map.Height)) && (num5 <= 0))
                {
                    GameScreen.LeftEdge = num4;
                    GameScreen.TopEdge = num5;
                }
                else
                {
                    MapUnit.Width = currentWidth;
                    MapUnit.Width = currentHeight;
                }
                GameScreen.ResetScreenEdge(MapUnit.Width, MapUnit.Height, Game.GraphicsDevice.Viewport);
            }
        }
        /// <summary>
        /// 地图跳转到制定位置
        /// </summary>
        /// <param name="mapPosition"></param>
        public static void MapJumpToDestination(Point mapPosition)
        {
            int num = (MapUnit.Width * mapPosition.X) + (MapUnit.Width / 2);
            int num2 = (MapUnit.Height * mapPosition.Y) + (MapUnit.Height / 2);
            GameScreen.LeftEdge = (GameScreen.ViewportSize.X / 2) - num;
            if (GameScreen.LeftEdge > 0)
            {
                GameScreen.LeftEdge = 0;
            }
            else if (GameScreen.LeftEdge < (GameScreen.ViewportSize.X - Map.Width))
            {
                GameScreen.LeftEdge = GameScreen.ViewportSize.X - Map.Width;
            }
            GameScreen.TopEdge = (GameScreen.ViewportSize.Y / 2) - num2;
            if (GameScreen.TopEdge > 0)
            {
                GameScreen.TopEdge = 0;
            }
            else if (GameScreen.TopEdge < (GameScreen.ViewportSize.Y - Map.Height))
            {
                GameScreen.TopEdge = GameScreen.ViewportSize.Y - Map.Height;
            }
            GameScreen.ResetScreenEdge(MapUnit.Width, MapUnit.Height, Game.GraphicsDevice.Viewport);
        }
        /// <summary>
        /// 位置是否超出地图尺寸
        /// </summary>
        /// <param name="position"></param>
        /// <returns></returns>
        public static bool PositionOutOfMap(Point position)
        {
            return ((((position.X < 0) || (position.Y < 0)) || (position.X >= Map.MapDimensions.X)) || (position.Y >= Map.MapDimensions.Y));
        }
        /// <summary>
        /// 鼠标左键单击事件处理器
        /// </summary>
        /// <param name="args"></param>
        public void ClickLeftEventHandler(object args)
        {
           

        }
    }



}
